<?php

declare(strict_types=1);

namespace App\Controller\Admin\V1\Publics;

use App\Constants\Admin\AdminCode;
use App\Controller\Admin\V1\Controllers;
use App\Event\Admin\Publics\AfterLogin;
use App\Model\Admin\Admin;
use App\Request\Publics\Login as LoginRequest;
use App\Services\Admin\Admin as AdminServices;
use App\Utils\Other\Jwt\Token;
use App\Utils\Other\VerifyCode\VerifyCode;
use Hyperf\Context\Context;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface;
use function Hyperf\Translation\__;

class Login extends Controllers
{
    /**
     * @var string
     */
    protected string $requestClass = LoginRequest::class;

    public function __construct(
        protected AdminServices $adminServices,
        private EventDispatcherInterface $eventDispatcher
    )
    {
        parent::__construct();
    }

    /**
     * 登录
     * @param LoginRequest $loginRequest
     * @param Token $token
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function save(Token $token)
    {
        $params = $this->input([
            'username',
            'password'
        ]);
        /** @var Admin $admin */
        $admin = $this->adminServices->findBy('username', $params['username']);
        logs($admin->toArray());
        if (!$admin || !password_verify($params['password'], $admin->password)) {
            return failed(__('message.login.password.failed'));
        }
        if ($admin->status != AdminCode::STATUS_NORMAL) {
            return failed(__('message.login.status', ['status' => AdminCode::getMessage($admin->status)]));
        }

        $data = $admin->makeHidden('password')->toArray();
        $tokenStr = $token->encode($data);

        Context::set('adminInfo', $data);

        $this->eventDispatcher->dispatch(new AfterLogin($admin));

        return success([
            'token' => $tokenStr
        ]);
    }

    /**
     * 登出
     * @param Token $token
     * @return \Psr\Http\Message\ResponseInterface
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function destroy(Token $token)
    {
        $tokenStr = getAuthorization();
        if (!$token->delete($tokenStr)) {
            return message(__('message.login.logout.failed'));
        }
        return message(__('message.login.logout.success'));
    }

    /**
     * 生成验证码
     * @param VerifyCode $verifyCode
     * @return Psr7ResponseInterface
     */
    public function code(VerifyCode $verifyCode):Psr7ResponseInterface
    {
        return $verifyCode->make();
    }
}
